package com.ytjj.qmyx.mall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.ytjj.common.api.CommonPage;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.constants.SysConfigConstants;
import com.ytjj.common.dto.mqdto.DynamicCommentDto;
import com.ytjj.common.dto.mqdto.DynamicLikeDto;
import com.ytjj.common.enums.WxCodeEnums;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.model.UsersResponse;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.service.WxUtils;
import com.ytjj.common.utils.*;
import com.ytjj.qmyx.mall.constants.*;
import com.ytjj.qmyx.mall.enums.*;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.dto.WeappLiveDataDto;
import com.ytjj.qmyx.mall.model.esmodel.DynamicEsDto;
import com.ytjj.qmyx.mall.model.request.*;
import com.ytjj.qmyx.mall.model.response.*;
import com.ytjj.qmyx.mall.model.vo.DynamicVO;
import com.ytjj.qmyx.mall.service.*;
import com.ytjj.qmyx.mall.utils.PathUtils;
import com.ytjj.qmyx.users.client.UsersClient;
import com.ytjj.qmyx.users.mapper.UsersInfoMapper;
import com.ytjj.qmyx.users.model.ExpertInfoDto;
import com.ytjj.qmyx.users.model.UsersDto;
import com.ytjj.qmyx.users.model.UsersExpertDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * 动态接口实现
 *
 *
 * @version 1.0
 *
 */
@Service
@Slf4j
public class DynamicServiceImpl implements DynamicService {

    @Resource
    private DynamicMapper dynamicMapper;

    private final UsersClient usersClient;

    private final SpecialService specialService;

    private final CommonService commonService;

    @Autowired
    private  SysConfigUtil sysConfigUtil;

    @Resource
    private DynamicCommentMapper dynamicCommentMapper;

    @Resource
    private DynamicLikeMapper dynamicLikeMapper;

    @Resource
    private DynamicCommentRelationMapper dynamicCommentRelationMapper;

    @Resource
    private DynamicDao dynamicDao;

    @Resource
    private ProductDao productDao;

    @Resource
    private BannersMapper bannersMapper;

    @Resource
    private DynamicCommentDao dynamicCommentDao;
    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private RedisService redisService;

    @Resource
    private DynamicMatchingMapper dynamicMatchingMapper;

    @Resource
    private DynamicBrowsingRecordMapper dynamicBrowsingRecordMapper;

    @Resource
    private DynamicBrowsingRecordDao dynamicBrowsingRecordDao;

    @Resource
    private OrdersInfoMapper ordersInfoMapper;

    @Resource
    private LiveMapper liveMapper;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Resource
    private LiveDao liveDao;

    @Resource
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private FrontCategoryService frontCategoryService;

    @Autowired
    private DynamicCommentReplyMapper dynamicCommentReplyMapper;

    @Autowired
    private DynamicCommentReplyDao dynamicCommentReplyDao;

    @Autowired
    private DynamicCommentLikeMapper dynamicCommentLikeMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductCategoryMapper productCategoryMapper;

    @Autowired
    private UsersInfoMapper usersInfoMapper;





    private final OrdersService ordersService;

    private final ProductService productService;

    @Resource
    private OrdersDao ordersDao;
    @Resource
    private EsService esService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Resource(name = "mallFrontCategoryMapper")
    private FrontCategoryMapper frontCategoryMapper;

    @Autowired
    private ProductServiceImpl productServiceImpl;

    public DynamicServiceImpl(UsersClient usersClient, SpecialService specialService, CommonService commonService, OrdersService ordersService, ProductService productService) {
        this.usersClient = usersClient;
        this.specialService = specialService;
        this.commonService = commonService;
        this.ordersService = ordersService;
        this.productService = productService;
    }

    @Override
    public List<DynamicResponse> getDynamicListByUserId(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        DynamicExample dynamicExample = new DynamicExample();
        // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
        if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
            dynamicExample.createCriteria()
                    .andUserIdEqualTo(userId)
                    .andProductTypeIn(Arrays.asList(1,2))
                    .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
        }else{
            dynamicExample.createCriteria()
                    .andUserIdEqualTo(userId)
                    .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
        }
        List<Dynamic> list = dynamicMapper.selectByExample(dynamicExample);
        return list.stream()
                .map(this::newDynamicResponse)
                .collect(Collectors.toList());
    }

    @Override
    public List<Dynamic> getDynamicIdsByUserId(Integer userId) {
        DynamicExample dynamicExample = new DynamicExample();
        dynamicExample.createCriteria().andUserIdEqualTo(userId).andStatusEqualTo(DynamicConstant.DYNAMIC_STATUS_PASS);
        List<Dynamic> list = dynamicMapper.selectByExample(dynamicExample);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list;
    }

    @Override
    public List<Dynamic> getDynamicIdsById(Integer productId) {
        return null;
    }

    @Override
    public List<DynamicVO> getDynamicIdsByVOId(Integer productId) {
        return dynamicDao.getDynamicIdsById(productId);
    }

    @Override
    public List<DynamicResponse> getDynamicListBySpecialId(Integer specialId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Dynamic> dynamics = dynamicDao.queryDynamicBySpecialId(specialId);
        return dynamics.stream()
                .map(this::newDynamicResponse)
                .collect(Collectors.toList());
    }

    @Override
    public DynamicPageResponse getDynamicPage() {
        DynamicPageResponse dynamicPageResponse = new DynamicPageResponse();
        dynamicPageResponse.setBannerUrl(commonService.getSysConfigValue(SysConfigConstants.DYNAMIC_BANNER_URL));
        List<UsersExpertDto> usersExpertDtoList = usersClient.getUsersExpertList(UsersExpertTypeEnums.SUPER.name());
        dynamicPageResponse.setUsersExpertList(usersExpertDtoList);
        List<UsersExpertDto> recommendUsersList = usersClient.getUsersExpertList(UsersExpertTypeEnums.NORMAL.name());
        dynamicPageResponse.setRecommendUsersList(recommendUsersList);
        List<BannersResponse> bannersResponseList = commonService.getBannersListByType(BannerTypeEnums.DYNAMIC_LIVE.name());
        dynamicPageResponse.setBannersResponseList(bannersResponseList);
        List<SpecialResponse> list = specialService.getSpecialListByType(SpecialTypeEnums.dynamic.name());
        dynamicPageResponse.setSpecialList(list);

        return dynamicPageResponse;
    }

    @Override
    public CommunityPageResponse getCommunityPage() {
        CommunityPageResponse communityPageResponse = new CommunityPageResponse();
        // 用户达人
        List<UsersExpertDto> usersExpertDtoList = usersClient.getUsersExpertList(UsersExpertTypeEnums.NORMAL.name());
        communityPageResponse.setUsersExpertList(usersExpertDtoList);
        // 社区banner
        // List<BannersResponse> bannersResponseList = commonService.getBannersListByType(BannerTypeEnums.COMMUNITY_IMG.name());
        // communityPageResponse.setBannersResponseList(bannersResponseList);
        communityPageResponse.setBannerUrl(commonService.getSysConfigValue(SysConfigConstants.DYNAMIC_BANNER_URL));
        // 《大家都在看》 热搜词列表 “DYNAMIC”
        List<Object> list = redisService.range(RedisConstants.HOT_SEARCH, 0, -1);
        list = list.stream()
                .map(cn.hutool.json.JSONObject::new)
                .filter(item -> item.getStr("type").equals("DYNAMIC"))
                .sorted(Comparator.comparing(item -> item.getInt("sort")))
                .collect(Collectors.toList());
        communityPageResponse.setHotSearchList(list);
        // 直播
        SysConfig sysConfig = sysConfigMapper.selectByPrimaryKey(SysConfigConstants.WX_TOKEN);
        Map<String,Object> param = new HashMap<>();
        param.put("start",0);
        param.put("limit",100);
        JSONObject liveList = WxUtils.getLiveList(sysConfig.getParamValue(),param);
        if(liveList.getInteger("errcode") == 0){
            JSONArray roomInfo = liveList.getJSONArray("room_info");
            if(roomInfo !=null && roomInfo.size()>0){
                List<WeappLiveDataDto> weappLiveDataDtos = JSONArray.parseArray(roomInfo.toJSONString(), WeappLiveDataDto.class);
                // 返回在直播的列表
                List<WeappLiveDataDto> collect = weappLiveDataDtos.stream().filter(item -> item.getLive_status() == 101).collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(collect)){
                    communityPageResponse.setWeappLive(collect.get(0));
                }
            }
        }
        LiveExample liveExample = new LiveExample();
        liveExample.createCriteria().andStatusEqualTo(2);
        List<Live> lives = liveMapper.selectByExample(liveExample);
        if(!CollectionUtils.isEmpty(lives)){
            communityPageResponse.setLive(lives.get(0));
        }

        return communityPageResponse;
    }

    @Override
    public List<DynamicEsResponse> getEsDynamicList(DynamicEsRequest dynamicEsRequest) {
        BoolQueryBuilder dynamicBoolQueryBuilder = new BoolQueryBuilder();
        // 查询用户标签
        dynamicBoolQueryBuilder.must(termQuery("status", ProductStatusEnums.UP.getValue()));
        // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
        if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
            dynamicBoolQueryBuilder.mustNot(termQuery("product_type",3));
        }
        Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
        SortBuilder sortBuilder = SortBuilders.fieldSort("is_reason").order(SortOrder.fromString(SortOrder.DESC.toString()));
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(dynamicBoolQueryBuilder)
                .withPageable(pageable)
                .withSort(sortBuilder)
                .build();
        List<DynamicEsDto> productEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
        List<DynamicEsResponse> dynamicEsResponseList= productEsDtoList.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        dynamicEsResponseList = dynamicEsResponseList.stream().map(item ->{
            // 动态类型
            item.setDynamicType("VIDEO");
            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            // 用户名称
            item.setUserName(usersDto.getNickname());
            // 用户头像
            item.setHeadImg(usersDto.getHeadImg());
            return  item;
        }).collect(Collectors.toList());

        return dynamicEsResponseList;
    }

    @Override
    public List<DynamicEsResponse> getEsDynamicList(DynamicEsRequest dynamicEsRequest,Integer userId) {
        BoolQueryBuilder dynamicBoolQueryBuilder = new BoolQueryBuilder();
        // 查询用户标签
        UsersDto usersInfoDto = usersClient.getUsersInfo(userId);
        String label = usersInfoDto.getLabelText();
        List<DynamicEsResponse> dynamicEsResponseList = null;
        // 查询后10条动态的记录
        List<DynamicBrowsingRecord> dynamicBrowsingRecordList = dynamicBrowsingRecordDao.selectLimit10(userId);
        String labelJson = dynamicBrowsingRecordList.stream()
                .filter(item -> StringUtils.isNotBlank(item.getLabelJson()))
                .map(item -> item.getLabelJson())
                .collect(Collectors.joining(","));

        if(StringUtils.isBlank(label)){
            // 该用户没有标签
            if(StringUtils.isBlank(labelJson)){
                dynamicBoolQueryBuilder.must(termQuery("status", ProductStatusEnums.UP.getValue()));
            }else{
                dynamicBoolQueryBuilder.must(multiMatchQuery(labelJson,"label_json"))
                        .must(termQuery("status", ProductStatusEnums.UP.getValue()));
            }
            // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
            if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
                dynamicBoolQueryBuilder.mustNot(termQuery("product_type",3));
            }
            Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
            SortBuilder sortBuilder = SortBuilders.fieldSort("is_reason").order(SortOrder.fromString(SortOrder.DESC.toString()));
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(dynamicBoolQueryBuilder)
                    .withPageable(pageable)
                    .withSort(sortBuilder)
                    .build();
            List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
            dynamicEsResponseList= dynamicEsDtoList.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        }else{
            labelJson = StringUtils.isNotBlank(labelJson) ? labelJson+","+label :label;
            dynamicBoolQueryBuilder.must(multiMatchQuery(labelJson,"label_json"))
                    .must(termQuery("status", ProductStatusEnums.UP.getValue()));
            // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
            if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
                dynamicBoolQueryBuilder.mustNot(termQuery("product_type",3));
            }
            Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
            SortBuilder sortBuilder = SortBuilders.fieldSort("is_reason").order(SortOrder.fromString(SortOrder.DESC.toString()));
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(dynamicBoolQueryBuilder)
                    .withPageable(pageable)
                    .withSort(sortBuilder)
                    .build();
            List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
            dynamicEsResponseList= dynamicEsDtoList.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        }

        dynamicEsResponseList = dynamicEsResponseList.stream().map(item ->{
            // 动态类型
            item.setDynamicType("VIDEO");
            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            // 用户名称
            item.setUserName(usersDto.getNickname());
            // 用户头像
            item.setHeadImg(usersDto.getHeadImg());
            // 是否喜欢
            Dynamic dynamic = new Dynamic();
            BeanUtils.copyProperties(item, dynamic);
            int praise = this.isPraise(dynamic);
            item.setIsLike(praise);
            return  item;
        }).collect(Collectors.toList());

        return dynamicEsResponseList;
    }

    @Override
    public List<DynamicResponse> getMyDynamicInfos(Integer dynamicId, Integer userId, Integer ortherUserId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        // 查询改动态
        DynamicDto dynamicDto = this.getDynamicById(dynamicId);
        // 查询用户对应的动态列表
        DynamicExample dynamicExample = new DynamicExample();
        if(ortherUserId !=null ){
            // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
            if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
                // 查询他人的动态信息列表
                dynamicExample.createCriteria()
                        .andUserIdEqualTo(ortherUserId)
                        .andProductTypeIn(Arrays.asList(1,2))
                        .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
            }else{
                // 查询他人的动态信息列表
                dynamicExample.createCriteria()
                        .andUserIdEqualTo(ortherUserId)
                        .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
            }
        }else{
            // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
            if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
                // 查询他人的动态信息列表
                dynamicExample.createCriteria()
                        .andUserIdEqualTo(ortherUserId)
                        .andProductTypeIn(Arrays.asList(1,2))
                        .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
            }else{
                // 查询自己的动态列表
                dynamicExample.createCriteria()
                        .andUserIdEqualTo(userId)
                        .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
            }
        }

        List<Dynamic> list = dynamicMapper.selectByExample(dynamicExample);
        List<DynamicDto> dynamicDtoList = list.stream().filter(item -> item.getId() != dynamicId)
                .map(item -> {
                    DynamicDto data = new DynamicDto();
                    BeanUtils.copyProperties(item,data);
                    return  data;
                }).collect(Collectors.toList());
        // 处理动态列表
        List<DynamicDto> dynamicDtoOf = new ArrayList<>();
        dynamicDtoOf.addAll(dynamicDtoList);
        if(dynamicDto != null){
            dynamicDtoOf.add(dynamicDto);
            Collections.swap(dynamicDtoOf,dynamicDtoOf.indexOf(dynamicDto),0);
        }
        List<DynamicResponse> collect = dynamicDtoOf.stream().map(item -> {
            DynamicResponse dynamicResponse = new DynamicResponse();
            BeanUtils.copyProperties(item, dynamicResponse);

            // 适配 h5
            if(userId != null){
                dynamicResponse.setIsOneself(userId.intValue() == Optional.ofNullable(dynamicResponse.getUserId()).orElse(0).intValue()? 1:0);
                if(dynamicResponse.getIsOneself() == 0){
                    // 不是自己
                    // 查询他人购物清单数量
                    dynamicResponse.setBuySum(ordersDao.countOrderInfoCountByUserId(item.getUserId()));
                }
                // 是否关注
                dynamicResponse.setIsAttention(usersClient.isAttention(userId, item.getUserId()));
                // 是否喜欢（收藏）
                dynamicResponse.setIsLike(this.isLike(item.getId(), userId));
            }else{
                dynamicResponse.setBuySum(ordersDao.countOrderInfoCountByUserId(item.getUserId()));
                dynamicResponse.setIsOneself(0);
                dynamicResponse.setIsAttention(0);
                dynamicResponse.setIsLike(0);
            }

            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            // 用户名称
            dynamicResponse.setUserName(usersDto.getNickname());
            // 用户头像
            dynamicResponse.setHeadImg(usersDto.getHeadImg());

            Product product = productDao.getProductById(item.getProductId());
            // 推荐商品数量
            ProductMatching productMatching = productDao.queryProductMatchingById(product.getId());
            if(productMatching == null || StringUtils.isBlank(productMatching.getLabelJson())){
                dynamicResponse.setSimilaritySum(0L);
            }else{
                BoolQueryBuilder activityBoolQueryBuilder = new BoolQueryBuilder()
                        .must(multiMatchQuery(productMatching.getLabelJson(), "label_json"))
                        .must(termQuery("status", ProductStatusEnums.UP.getValue()));
                SearchQuery dynamicRecommendQuery = new NativeSearchQueryBuilder()
                        .withQuery(activityBoolQueryBuilder)
                        .withIndices(EsConstant.MYSQL_PRODUCT, EsConstant.MYSQL_PRODUCT_ACTIVITY)
                        .build();
                Long count = esService.count(dynamicRecommendQuery);
                dynamicResponse.setSimilaritySum(count);
            }
            // 商品状态
            Integer productStatus = productService.getProductStatusByProductId(item.getProductId());
            dynamicResponse.setProductStatus(productStatus);
            // 商品原价
            dynamicResponse.setOriginalPrice(product.getOriginalPrice());
            // 商品价格
            dynamicResponse.setProdcutPrice(product.getPrice());
            // 动态类型
            dynamicResponse.setDynamicType("VIDEO");

            // 商品模型
            ProductResponse response = productService.queryProductById(item.getProductId());
            response.setSpecMap(productService.getProductSpecList(response.getId()).stream()
                    .collect(Collectors.toMap(specItem -> {
                        String skuSpec = specItem.getSkuSpec();
                        String[] specList = skuSpec.split(",");
                        StringBuilder stringBuilder = new StringBuilder();
                        for (int i = 0; i < specList.length; i++) {
                            String key = specList[i].split(":")[1];
                            if (i == specList.length - 1) {
                                stringBuilder.append(key);
                            } else {
                                stringBuilder.append(key).append("-");
                            }
                        }
                        return stringBuilder.toString();
                    }, specItem -> specItem)));
            dynamicResponse.setProductInfo(response);
            dynamicResponse.setProductType(response.getProductType());// 不给ProductType赋值,到后续操作ProductType为null转换为Integer时,会报错
            return dynamicResponse;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<DynamicEsResponse> getEsDynamicInfos(DynamicEsRequest dynamicEsRequest) {
        BoolQueryBuilder dynamicBoolQueryBuilder = new BoolQueryBuilder();
        // 查询用户标签
        List<DynamicEsResponse> dynamicEsResponseList = null;
        if(!StringUtils.isBlank(dynamicEsRequest.getLabelText())){
            dynamicBoolQueryBuilder.must(multiMatchQuery(dynamicEsRequest.getLabelText(),"label_json"))
                    .must(matchQuery("dynamic_type","video"))
                    .must(termQuery("status", ProductStatusEnums.UP.getValue()));
            Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(dynamicBoolQueryBuilder)
                    .withPageable(pageable)
                    .build();
            List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
            dynamicEsResponseList= dynamicEsDtoList.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        }else{
            Integer dynamicId = dynamicEsRequest.getDynamicId();
            DynamicEsDto dynamicEsDto = null;
            if(dynamicId !=null){
                dynamicEsDto = new DynamicEsDto();
                Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
                BeanUtils.copyProperties(dynamic,dynamicEsDto);
            }
            dynamicBoolQueryBuilder.must(termQuery("status", ProductStatusEnums.UP.getValue()))
                                    .must(matchQuery("dynamic_type","video"));
            Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(dynamicBoolQueryBuilder)
                    .withPageable(pageable)
                    .build();
            List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
            if(dynamicId != null){
                dynamicEsDtoList = dynamicEsDtoList.stream().filter(item -> !item.getId().equals(dynamicId)).collect(Collectors.toList());
            }
            Collections.shuffle(dynamicEsDtoList);
            List<DynamicEsDto> dynamicEsDtoOf = new ArrayList<>();
            dynamicEsDtoOf.addAll(dynamicEsDtoList);
            if(dynamicEsDto != null){
                dynamicEsDtoOf.add(dynamicEsDto);
                Collections.swap(dynamicEsDtoOf,dynamicEsDtoOf.indexOf(dynamicEsDto),0);
            }
            dynamicEsResponseList= dynamicEsDtoOf.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        }
        dynamicEsResponseList = dynamicEsResponseList.stream().map(item ->{
            item.setProductType(item.getProductType() != null && item.getProductType() == 3 ? 3 : StringUtils.isNotEmpty(item.getActivityType()) ? 2 : 1);

            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            // 用户名称
            item.setUserName(usersDto.getNickname());
            // 用户头像
            item.setHeadImg(usersDto.getHeadImg());
            // 用户性别
            item.setSex(usersDto.getSex());
            // 动态类型
            item.setDynamicType("VIDEO");
            // 购买数量
            item.setBuySum(ordersDao.countOrderInfoCountByUserId(item.getUserId()));
            // 是否自己发布的作品 0-非本人发布 1-本人发布
            item.setIsOneself(0);
            // 点赞
            item.setIsLike(0);
            // 推荐商品数量
            Product product = productDao.getProductById(item.getProductId());
            ProductMatching productMatching = productDao.queryProductMatchingById(product.getId());
            if(productMatching == null || StringUtils.isBlank(productMatching.getLabelJson())){
                item.setSimilaritySum(0L);
            }else{
                BoolQueryBuilder activityBoolQueryBuilder = new BoolQueryBuilder()
                        .must(multiMatchQuery(productMatching.getLabelJson(), "label_json"))
                        .must(termQuery("status", ProductStatusEnums.UP.getValue()));
                SearchQuery dynamicRecommendQuery = new NativeSearchQueryBuilder()
                        .withQuery(activityBoolQueryBuilder)
                        .withIndices(EsConstant.MYSQL_PRODUCT, EsConstant.MYSQL_PRODUCT_ACTIVITY)
                        .build();
                Long count = esService.count(dynamicRecommendQuery);
                item.setSimilaritySum(count);
            }

            // 商品状态
            Integer productStatus = productService.getProductStatusByProductId(item.getProductId());
            item.setProductStatus(productStatus);
            // 商品原价
            item.setOriginalPrice(product.getOriginalPrice());
            // 商品价格
            item.setProdcutPrice(product.getPrice());

            // 商品模型
            ProductResponse response = productService.queryProductById(item.getProductId());
            response.setSpecMap(productService.getProductSpecList(response.getId()).stream()
                    .collect(Collectors.toMap(specItem -> {
                        String skuSpec = specItem.getSkuSpec();
                        String[] specList = skuSpec.split(",");
                        StringBuilder stringBuilder = new StringBuilder();
                        for (int i = 0; i < specList.length; i++) {
                            String key = specList[i].split(":")[1];
                            if (i == specList.length - 1) {
                                stringBuilder.append(key);
                            } else {
                                stringBuilder.append(key).append("-");
                            }
                        }
                        return stringBuilder.toString();
                    }, specItem -> specItem)));
            item.setProductInfo(response);
            return  item;
        }).collect(Collectors.toList());
        return dynamicEsResponseList;
    }

    @Override
    public List<DynamicEsResponse> getEsDynamicInfos(DynamicEsRequest dynamicEsRequest, Integer userId) {
        BoolQueryBuilder dynamicBoolQueryBuilder = new BoolQueryBuilder();
        // 查询用户标签
        UsersDto usersInfoDto = usersClient.getUsersInfo(userId);
        String label = usersInfoDto.getLabelText();
        List<DynamicEsResponse> dynamicEsResponseList = null;
        if(!StringUtils.isBlank(dynamicEsRequest.getLabelText())){
            dynamicBoolQueryBuilder.must(multiMatchQuery(dynamicEsRequest.getLabelText(),"label_json"))
                    .must(termQuery("status", ProductStatusEnums.UP.getValue()));
            Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(dynamicBoolQueryBuilder)
                    .withPageable(pageable)
                    .build();
            List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
            List<DynamicEsDto> dynamicEsDtoOf = new ArrayList<>();
            dynamicEsDtoOf.addAll(dynamicEsDtoList);
            Collections.shuffle(dynamicEsDtoOf);
            dynamicEsResponseList= dynamicEsDtoOf.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
        }else{
            Integer dynamicId = dynamicEsRequest.getDynamicId();
            DynamicEsDto dynamicEsDto = null;
            if(dynamicId !=null){
                dynamicEsDto = new DynamicEsDto();
                Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
                BeanUtils.copyProperties(dynamic,dynamicEsDto);
            }
            // 查询后10条动态的记录
            List<DynamicBrowsingRecord> dynamicBrowsingRecordList = dynamicBrowsingRecordDao.selectLimit10(userId);

            String labelJson = dynamicBrowsingRecordList.stream().filter(item -> StringUtil.isNotEmpty(item.getLabelJson())).map(item -> item.getLabelJson()).collect(Collectors.joining(","));

            if(StringUtils.isBlank(label)){
                // 该用户没有标签
                if(StringUtils.isBlank(labelJson)){
                    dynamicBoolQueryBuilder.must(termQuery("status", ProductStatusEnums.UP.getValue()));
                }else{
                    dynamicBoolQueryBuilder.must(multiMatchQuery(labelJson,"label_json"))
                            .must(termQuery("status", ProductStatusEnums.UP.getValue()));
                }
                Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
                SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withQuery(dynamicBoolQueryBuilder)
                        .withPageable(pageable)
                        .build();
                List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
                if(dynamicId != null){
                    dynamicEsDtoList = dynamicEsDtoList.stream().filter(item -> item.getId() != dynamicId).collect(Collectors.toList());
                }
                Collections.shuffle(dynamicEsDtoList);
                List<DynamicEsDto> dynamicEsDtoOf = new ArrayList<>();
                dynamicEsDtoOf.addAll(dynamicEsDtoList);
                if(dynamicEsDto != null){
                    dynamicEsDtoOf.add(dynamicEsDto);
                    Collections.swap(dynamicEsDtoOf,dynamicEsDtoOf.indexOf(dynamicEsDto),0);
                }
                dynamicEsResponseList= dynamicEsDtoOf.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
            }else{
                labelJson = StringUtils.isNotBlank(labelJson) ? labelJson+","+label :label;
                dynamicBoolQueryBuilder.must(multiMatchQuery(labelJson,"label_json"))
                        .must(termQuery("status", ProductStatusEnums.UP.getValue()));
                Pageable pageable = PageRequest.of(dynamicEsRequest.getPageNum()-1, dynamicEsRequest.getPageSize());
                SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withQuery(dynamicBoolQueryBuilder)
                        .withPageable(pageable)
                        .build();
                List<DynamicEsDto> dynamicEsDtoList = template.queryForList(searchQuery, DynamicEsDto.class);
                if(dynamicId != null){
                    dynamicEsDtoList = dynamicEsDtoList.stream().filter(item -> item.getId() != dynamicId).collect(Collectors.toList());
                }
                Collections.shuffle(dynamicEsDtoList);
                List<DynamicEsDto> dynamicEsDtoOf = new ArrayList<>();
                dynamicEsDtoOf.addAll(dynamicEsDtoList);
                if(dynamicEsDto != null){
                    dynamicEsDtoOf.add(dynamicEsDto);
                    Collections.swap(dynamicEsDtoOf,dynamicEsDtoOf.indexOf(dynamicEsDto),0);
                }
                dynamicEsResponseList = dynamicEsDtoOf.stream().map(DynamicEsResponse::new).collect(Collectors.toList());
            }
        }

        dynamicEsResponseList = dynamicEsResponseList.stream().map(item ->{
            item.setProductType(item.getProductType() != null && item.getProductType() == 3 ? 3 : StringUtils.isNotEmpty(item.getActivityType()) ? 2 : 1);

            item.setIsOneself(userId.intValue() == Optional.ofNullable(item.getUserId()).orElse(0).intValue()? 1:0);
            if(item.getIsOneself() == 0){
                // 不是自己
                // 查询他人购物清单数量
                item.setBuySum(ordersDao.countOrderInfoCountByUserId(item.getUserId()));
            }
            // 是否关注
            item.setIsAttention(usersClient.isAttention(userId, item.getUserId()));
            // 是否喜欢（收藏）
            item.setIsLike(this.isLike(item.getId(), userId));

            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            // 用户名称
            item.setUserName(usersDto.getNickname());
            // 用户头像
            item.setHeadImg(usersDto.getHeadImg());
            // 用户性别
            item.setSex(usersDto.getSex());
            // 动态类型
            item.setDynamicType("VIDEO");
            // 推荐商品数量
            Product product = productDao.getProductById(item.getProductId());
            ProductMatching productMatching = productDao.queryProductMatchingById(product.getId());
            if(productMatching == null || StringUtils.isBlank(productMatching.getLabelJson())){
                item.setSimilaritySum(0L);
            }else{
                dynamicBoolQueryBuilder.must(multiMatchQuery(productMatching.getLabelJson(),"label_json"));
                SearchQuery dynamicRecommendQuery = new NativeSearchQueryBuilder()
                        .withQuery(dynamicBoolQueryBuilder)
                        .withIndices(EsConstant.MYSQL_PRODUCT)
                        .build();
                Long count = esService.count(dynamicRecommendQuery);
                item.setSimilaritySum(count);
            }

            // 商品状态
            Integer productStatus = productService.getProductStatusByProductId(item.getProductId());
            item.setProductStatus(productStatus);
            // 商品原价
            item.setOriginalPrice(product.getOriginalPrice());
            // 商品价格
            item.setProdcutPrice(product.getPrice());

            // 商品模型
            ProductResponse response = productService.queryProductById(item.getProductId());
            response.setSpecMap(productService.getProductSpecList(response.getId()).stream()
                    .collect(Collectors.toMap(specItem -> {
                        String skuSpec = specItem.getSkuSpec();
                        String[] specList = skuSpec.split(",");
                        StringBuilder stringBuilder = new StringBuilder();
                        for (int i = 0; i < specList.length; i++) {
                            String key = specList[i].split(":")[1];
                            if (i == specList.length - 1) {
                                stringBuilder.append(key);
                            } else {
                                stringBuilder.append(key).append("-");
                            }
                        }
                        return stringBuilder.toString();
                    }, specItem -> specItem)));
            item.setProductInfo(response);

            return  item;
        }).collect(Collectors.toList());

        return dynamicEsResponseList;
    }

    @Autowired
    private ElasticsearchTemplate template;

    @Override
    public DynamicResponse getDynamicInfo(Integer dynamicId) {
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
        DynamicResponse dynamicResponse = this.newDynamicResponse(dynamic);
        Integer productStatus = productService.getProductStatusByProductId(dynamic.getProductId());
        Product product = productDao.getProductById(dynamic.getProductId());
        ProductMatching productMatching = productDao.queryProductMatchingById(product.getId());
        BoolQueryBuilder productBoolQueryBuilder = new BoolQueryBuilder()
                .must(multiMatchQuery(productMatching.getLabelJson(), "label_json"))
                .must(termQuery("status", ProductStatusEnums.UP.getValue()));
        SearchQuery productRecommendQuery = new NativeSearchQueryBuilder()
                .withQuery(productBoolQueryBuilder)
                .withIndices(EsConstant.MYSQL_PRODUCT, EsConstant.MYSQL_PRODUCT_ACTIVITY)
                .build();
//        long count = template.count(productRecommendQuery, ProductEsDto.class);
//
//        BoolQueryBuilder activityBoolQueryBuilder = new BoolQueryBuilder()
//                .must(multiMatchQuery(productMatching.getLabelJson(), "label_json"))
//                .must(termQuery("status", ProductStatusEnums.UP.getValue()));
//        SearchQuery activityRecommendQuery = new NativeSearchQueryBuilder()
//                .withQuery(activityBoolQueryBuilder)
//                .build();
//        count = count + template.count(activityRecommendQuery, ProductActivityEsDto.class);
        Long count = esService.count(productRecommendQuery);
        dynamicResponse.setSimilaritySum(count);
        dynamicResponse.setProductStatus(productStatus);
        dynamicResponse.setOriginalPrice(product.getOriginalPrice());
        dynamicResponse.setProdcutPrice(product.getPrice());
        return dynamicResponse;
    }

    @Override
    public List<DynamicCommentResponse> getDynamicComment(Integer dynamicId, Integer pid) {
        PageHelper.startPage(1, 5);
        DynamicCommentExample example = new DynamicCommentExample();
        example.setOrderByClause("sort desc");
        example.createCriteria()
                .andPidEqualTo(pid)
                .andStatusEqualTo(1)
                .andDynamicIdEqualTo(dynamicId);
        List<DynamicComment> dynamicComments = dynamicCommentMapper.selectByExample(example);
        return dynamicComments.stream().map(item -> {
            DynamicCommentResponse dynamicCommentResponse = new DynamicCommentResponse();
            BeanUtils.copyProperties(item, dynamicCommentResponse);
            UsersDto usersDto = usersClient.getUsersInfo(item.getUserId());
            dynamicCommentResponse.setNickname(usersDto.getNickname());
            dynamicCommentResponse.setHeadImg(usersDto.getHeadImg());
            dynamicCommentResponse.setDynamicCommentResponses(this.getDynamicComment(dynamicCommentResponse.getDynamicId(), dynamicCommentResponse.getId()));
            return dynamicCommentResponse;
        }).collect(Collectors.toList());
    }

    @Override
    public Integer isLike(Integer dynamicId, Integer userId) {
        DynamicLikeExample example = new DynamicLikeExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andDynamicIdEqualTo(dynamicId);
        long count = dynamicLikeMapper.countByExample(example);
        return count > 0 ? IsLikeConstant.YES : IsLikeConstant.NO;
    }

    @Override
    public Integer countLike(Integer dynamicId, Integer userId) {
        DynamicLikeExample example = new DynamicLikeExample();
        example.createCriteria()
                .andDynamicIdEqualTo(dynamicId);
        Long count = dynamicLikeMapper.countByExample(example);

        if (count == null || count < 0) {
            count = 0L;
        }
        return count.intValue();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void like(Integer dynamicId, Integer userId) {
        if (this.isLike(dynamicId, userId).equals(IsLikeConstant.YES)) {
            return;
        }
        DynamicLike dynamicLike = new DynamicLike();
        dynamicLike.setUserId(userId);
        dynamicLike.setDynamicId(dynamicId);
        dynamicLike.setCreateTime(new Date());
        dynamicLikeMapper.insertSelective(dynamicLike);

        // 动态发布用户点赞数 +1
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
        dynamic.setPraiseNum(dynamic.getPraiseNum() + 1);
        dynamicMapper.updateByPrimaryKeySelective(dynamic);

        // 加点赞
        usersClient.addPraise(dynamic.getUserId());
        // 商品浏览记录
        BrowsingHistoryRequest browsingHistoryRequest = new BrowsingHistoryRequest();
        browsingHistoryRequest.setDynamicId(dynamicId);
        saveBrowsingHistory(browsingHistoryRequest,userId,DynamicOperationEnum.LIKE.name());

        try {
            DynamicLikeDto dynamicLikeDto = new DynamicLikeDto();
            BeanUtils.copyProperties(dynamicLike, dynamicLikeDto);
            rabbitTemplate.convertAndSend(QueueConstants.APP_DYNAMIC_LIKE, JSONObject.toJSONString(dynamicLikeDto));
        } catch (Exception e) {
            log.error("===点赞埋点异常==={}", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelLike(Integer dynamicId, Integer userId) {
        if (this.isLike(dynamicId, userId).equals(IsLikeConstant.NO)) {
            return;
        }
        DynamicLikeExample example = new DynamicLikeExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andDynamicIdEqualTo(dynamicId);
        dynamicLikeMapper.deleteByExample(example);

        // 动态发布用户点赞数 -1
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
        dynamic.setPraiseNum(dynamic.getPraiseNum() - 1);
        dynamicMapper.updateByPrimaryKeySelective(dynamic);
        // 减点赞
        usersClient.subPraise(dynamic.getUserId());
    }

    @Override
    public Integer isLikeComment(Integer dynamicCommentId, Integer userId) {
        DynamicCommentRelationExample example = new DynamicCommentRelationExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andDynamicCommentIdEqualTo(dynamicCommentId);
        long count = dynamicCommentRelationMapper.countByExample(example);
        return count > 0 ? IsLikeConstant.YES : IsLikeConstant.NO;
    }

    @Override
    public Integer countLikeComment(Integer dynamicCommentId, Integer userId) {
        DynamicCommentRelationExample example = new DynamicCommentRelationExample();
        example.createCriteria()
                .andDynamicCommentIdEqualTo(dynamicCommentId);
        Long count = dynamicCommentRelationMapper.countByExample(example);

        if (count == null || count < 0) {
            count = 0L;
        }
        return count.intValue();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void likeComment(Integer dynamicCommentId, Integer userId) {
        if (this.isLikeComment(dynamicCommentId, userId).equals(IsLikeConstant.YES)) {
            return;
        }
        DynamicCommentRelation dynamicCommentRelation = new DynamicCommentRelation();
        dynamicCommentRelation.setUserId(userId);
        dynamicCommentRelation.setDynamicCommentId(dynamicCommentId);
        dynamicCommentRelation.setCreateTime(new Date());
        dynamicCommentRelationMapper.insertSelective(dynamicCommentRelation);

        // 动态发布用户点赞数 +1
        DynamicComment dynamicComment = Optional.ofNullable(dynamicCommentMapper.selectByPrimaryKey(dynamicCommentId))
                .orElse(new DynamicComment());
        dynamicComment.setLikeNum(Optional.ofNullable(dynamicComment.getLikeNum())
                .orElse(0) + 1);
        dynamicCommentMapper.updateByPrimaryKeySelective(dynamicComment);

        // 加点赞
//        usersClient.addPraise(dynamic.getUserId());
        // 商品浏览记录
//        BrowsingHistoryRequest browsingHistoryRequest = new BrowsingHistoryRequest();
//        browsingHistoryRequest.setDynamicId(dynamicId);
//        saveBrowsingHistory(browsingHistoryRequest,userId,DynamicOperationEnum.LIKE.name());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelLikeComment(Integer dynamicCommentId, Integer userId) {
        if (this.isLikeComment(dynamicCommentId, userId).equals(IsLikeConstant.NO)) {
            return;
        }
        DynamicCommentRelationExample example = new DynamicCommentRelationExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andDynamicCommentIdEqualTo(dynamicCommentId);
        dynamicCommentRelationMapper.deleteByExample(example);

        // 动态发布用户点赞数 -1
        DynamicComment dynamicComment = dynamicCommentMapper.selectByPrimaryKey(dynamicCommentId);
        int likeNum = 0;
        if (dynamicComment.getLikeNum() != null && dynamicComment.getLikeNum() > 0) {
            likeNum = dynamicComment.getLikeNum() - 1;
        }
        dynamicComment.setLikeNum(likeNum);
        dynamicCommentMapper.updateByPrimaryKeySelective(dynamicComment);
        // 减点赞
//        usersClient.subPraise(dynamic.getUserId());
    }

    @Override
    public int addComment(CommentRequest request) {
        if (SensitiveWordUtil.contains(request.getContent())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SENSITIVE_WORDS));
        }
        JSONObject jsonObject = WxUtils.msgSecCheck(commonService.getSysConfigValue(SysConfigConstants.WX_TOKEN), request.getContent());
        if (WxCodeEnums.CODE_87014.getCode().equals(jsonObject.getInteger("errCode"))) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SENSITIVE_WORDS));
        }
        DynamicComment dynamicComment = new DynamicComment();
        dynamicComment.setContent(request.getContent());
        dynamicComment.setCreateTime(new Date());
        dynamicComment.setDynamicId(request.getDynamicId());
        dynamicComment.setUserId(request.getUserId());
        dynamicComment.setSort(1);
        dynamicComment.setPid(Optional.ofNullable(request.getPid())
                .orElse(0));
        dynamicComment.setStarLevel(request.getStarLevel());
        dynamicComment.setFlag(request.getFlag());
        dynamicCommentMapper.insertSelective(dynamicComment);
        // 动态评论数 + 1
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(request.getDynamicId());
        dynamic.setCommentNum(dynamic.getCommentNum() + 1);
        dynamicMapper.updateByPrimaryKeySelective(dynamic);

        // 商品浏览记录
        BrowsingHistoryRequest browsingHistoryRequest = new BrowsingHistoryRequest();
        browsingHistoryRequest.setDynamicId(request.getDynamicId());
        saveBrowsingHistory(browsingHistoryRequest,request.getUserId(),DynamicOperationEnum.COMMENT.name());

        return doGiveScore(request.getUserId(), "5");
    }

    /**
     * 赠送积分
     */
    private int doGiveScore(Integer userId, String type) {
        Random random = new Random();
        int score = 20 + random.nextInt(4);
        try {
            usersClient.addScore(score, userId, type);
        } catch (Exception e) {
            log.error("===用户赠送发表评论积分异常==={},{}", userId, score);
        }
        return score;
    }

    @Override
    public ExpertDynamicResponse getExpertDynamicList(Integer expertId) {
        ExpertDynamicResponse expertDynamicResponse = new ExpertDynamicResponse();
        UsersExpertDto usersExpertDto = usersClient.getUsersExpertId(expertId);
        expertDynamicResponse.setUsersExpert(usersExpertDto);
        DynamicExample dynamicExample = new DynamicExample();
        dynamicExample.createCriteria()
                .andUserIdEqualTo(usersExpertDto.getUserId());
        List<Dynamic> list = dynamicMapper.selectByExample(dynamicExample);
        expertDynamicResponse.setDynamicList(list.stream()
                .map(this::newDynamicResponse)
                .collect(Collectors.toList()));
        return expertDynamicResponse;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void issueDynamic(IssueDynamicRequest request) {
        OrderInfoResponse orderInfo = ordersService.getOrderInfoById(request.getOrderInfoId());
        if (IsAppraiseConstant.CHECK.equals(orderInfo.getIsAppraise())) {
            // 审核中
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.DYNAMIC_LATE_PUBLISH));
        }
        // 插入动态
        Dynamic dynamic = new Dynamic();
        dynamic.setUserId(request.getUserId());
        dynamic.setVideo(request.getVideo());
        dynamic.setImg(orderInfo.getProductImg());
        dynamic.setTitle(request.getContent());
        dynamic.setContent(request.getContent());
        dynamic.setOrderInfoId(request.getOrderInfoId());
        dynamic.setActivityType(orderInfo.getActivityType());
        dynamic.setProductId(orderInfo.getProductId());
        dynamic.setProductImg(orderInfo.getProductImg());
        dynamic.setProductName(orderInfo.getProductName());
        dynamic.setProdcutPrice(orderInfo.getProductPrice());
        dynamic.setCreateTime(new Date());
        dynamic.setUpdateTime(new Date());
        dynamicMapper.insertSelective(dynamic);
        // 更新订单信息
        orderInfo.setIsAppraise(IsAppraiseConstant.CHECK);
        ordersService.updateOrderInfo(orderInfo);
    }

    @Override
    public H5DynamicResponse getH5DynamicList() {

        return null;
    }

    @Override
    public BannersResponse getBannersInfoByType(String type) {
        BannersExample bannersExample = new BannersExample();
        bannersExample.createCriteria()
                .andTypeEqualTo(type)
                .andStatusEqualTo(BannerStatusEnums.SHOW.getValue());
        List<Banners> banners = bannersMapper.selectByExample(bannersExample);
        if("v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
            banners = banners.stream().map(item -> {
                item.setAPath(PathUtils.replaceUrl(item.getAPath()));
                return item;
            })
                    .collect(Collectors.toList());
        }
        return new BannersResponse(banners.get(0));
    }


    @Override
    public DynamicExpertUserInfoResponse getH5ExpertInfoById(Integer userId) {
        ExpertInfoDto expertInfoDto = usersClient.getExpertInfoByUserId(userId);
        // 评论总数
        Integer dynamicCommentCount = dynamicCommentDao.getDynamicCount(userId);
        Integer dynamicCount = dynamicDao.getDynamicCount(userId);
        // 获取用户动态列表
        DynamicExample dynamicExample = new DynamicExample();
        dynamicExample.createCriteria()
                .andUserIdEqualTo(userId);
        List<Dynamic> dynamicList = Optional.ofNullable(dynamicMapper.selectByExample(dynamicExample))
                .orElse(new ArrayList<>());
        List<DynamicResponse> DynamicResponseList = dynamicList.stream()
                .map(this::newDynamicResponse).collect(Collectors.toList());

        expertInfoDto.setCommentNum(dynamicCommentCount)
                .setDynamicSum(dynamicCount);
        DynamicExpertUserInfoResponse dynamicExpertUserInfoResponse = new DynamicExpertUserInfoResponse()
                .setExpertInfoDto(expertInfoDto)
                .setDynamicList(DynamicResponseList);
        return dynamicExpertUserInfoResponse;
    }

    @Override
    public List<DynamicResponse> getH5DynamicVideoList(DynamicRequest dynamicRequest) {
        PageHelper.startPage(dynamicRequest.getPageNum(), dynamicRequest.getPageSize());
        List<Dynamic> h5DynamicVideoList = dynamicDao.getH5DynamicVideoList(dynamicRequest.getIsReason());
        return h5DynamicVideoList.stream()
                .map(item -> {
                    UsersDto usersInfo = usersClient.getUsersInfo(item.getUserId());
                    return new DynamicResponse(item, usersInfo);
                })
                .collect(Collectors.toList());

    }

    @Override
    public List<Product> getLiveProductList() {
        return productDao.getLiveProductList();
    }

    @Override
    public Integer countComment(Integer dynamicId) {
        DynamicCommentExample dynamicCommentExample = new DynamicCommentExample();
        dynamicCommentExample.createCriteria()
                .andDynamicIdEqualTo(dynamicId);
        Long count = dynamicCommentMapper.countByExample(dynamicCommentExample);
        return count.intValue();
    }

    @Override
    public Integer talentDynamicNum(Integer userId) {
        return dynamicMapper.talentDynamicNum(userId);
    }

    @Override
    public void saveBrowsingHistory(BrowsingHistoryRequest browsingHistoryRequest, Integer userId, String type) {
        Integer dynamicId = browsingHistoryRequest.getDynamicId();
        if(dynamicId == null){
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.DYNAMIC_ID_NOT_NULL));
        }
        if(userId == null){
            // 不记录
            return;
        }
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(dynamicId);
        DynamicBrowsingRecord dynamicBrowsingRecord = new DynamicBrowsingRecord();
        dynamicBrowsingRecord.setUserId(userId);
        dynamicBrowsingRecord.setDynamicId(dynamicId);
        dynamicBrowsingRecord.setDynamicName(dynamic.getTitle());
        // 操作类型
        dynamicBrowsingRecord.setType(type);
        dynamicBrowsingRecord.setProductId(dynamic.getProductId());
        dynamicBrowsingRecord.setProductName(dynamic.getProductName());

        DynamicMatchingExample dynamicMatchingExample = new DynamicMatchingExample();
        dynamicMatchingExample.createCriteria().andDynamicIdEqualTo(dynamicId);
        List<DynamicMatching> dynamicMatchingList = dynamicMatchingMapper.selectByExample(dynamicMatchingExample);
        if(!CollectionUtils.isEmpty(dynamicMatchingList)){
            DynamicMatching dynamicMatching = dynamicMatchingList.get(0);
            dynamicBrowsingRecord.setSex(dynamicMatching.getSex());
            dynamicBrowsingRecord.setComsumerPower(dynamicMatching.getComsumerPower());
            dynamicBrowsingRecord.setAgeRange(dynamicMatching.getAgeStr());
            dynamicBrowsingRecord.setProvinceJson(dynamicMatching.getProvinceJson());
            dynamicBrowsingRecord.setLabelJson(dynamicMatching.getLabelJson());
        }
        dynamicBrowsingRecord.setIp(IPUtil.getIpAddress(TokenUtil.getRequest()));
        dynamicBrowsingRecord.setCreateTime(new Date());
        dynamicBrowsingRecordMapper.insert(dynamicBrowsingRecord);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DynamicResponse publishShippingDynamic(ShippingDynamicRequest shippingDynamicRequest, UsersResponse usersResponse) {
        OrdersInfo orderInfo = ordersService.getOrdersInfoById(shippingDynamicRequest.getOrderInfoId());
        OrdersExample ordersExample = new OrdersExample();
        ordersExample.createCriteria()
                .andUserIdEqualTo(shippingDynamicRequest.getUserId())
                .andIdEqualTo(orderInfo.getOrderId());
        List<Orders> orders = ordersMapper.selectByExample(ordersExample);
        if(orders.size() <= 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.PUBLISH_FAIL));
        } else {
            if(DynamicConstant.IS_APPRAISE_BETWEEN.equals(orderInfo.getIsAppraise()) ||
                    DynamicConstant.IS_APPRAISE_YES.equals(orderInfo.getIsAppraise())) {

                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.ALREADY_PUBLISH));
            }
        }
        DynamicResponse dynamicResponse = new DynamicResponse();
        dynamicResponse.setUserName(usersResponse.getNickname());
        dynamicResponse.setHeadImg(usersResponse.getHeadImg());
        if(DynamicConstant.IS_APPRAISE_NO.equals(orderInfo.getIsAppraise())) {
            Dynamic dynamic = new Dynamic();
            dynamic.setUserId(shippingDynamicRequest.getUserId());
            dynamic.setVideo(shippingDynamicRequest.getVideo());
            dynamic.setImg(shippingDynamicRequest.getCoverImg());
            dynamic.setTitle(shippingDynamicRequest.getTitle());
            dynamic.setContent(shippingDynamicRequest.getRecommendReason());
            dynamic.setOrderInfoId(orderInfo.getId());
            dynamic.setCreateTime(new Date());
            BeanUtils.copyProperties(orderInfo, dynamic);
            dynamic.setProdcutPrice(orderInfo.getProductOprice());
            dynamicMapper.insertSelective(dynamic);
            BeanUtils.copyProperties(dynamic, dynamicResponse);
            dynamicResponse.setId(dynamic.getId());
            dynamicResponse.setProdcutPrice(orderInfo.getProductPrice());
            dynamicResponse.setOriginalPrice(orderInfo.getProductOprice());
            orderInfo.setIsAppraise(DynamicConstant.IS_APPRAISE_BETWEEN);
            ordersInfoMapper.updateByPrimaryKeySelective(orderInfo);
        }
        // 有无可发布商品列表
        Integer ordersInfoCount = ordersService.getOrdersInfoCount(shippingDynamicRequest.getUserId());
        if(ordersInfoCount <= 0) {
            dynamicResponse.setPublishFlag(false);
        } else {
            dynamicResponse.setPublishFlag(true);
        }
        return dynamicResponse;
    }

    @Override
    public Object getDynamicsList(String type, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        if (DynamicPageTypeConstant.RECOMMEND.equals(type)) {
            List<Dynamic> dynamics = dynamicDao.queryDynamicList();
            return dynamics.stream()
                    .map(this::newDynamicResponse)
                    .collect(Collectors.toList());
        } else if (DynamicPageTypeConstant.LIVE.equals(type)) {
            LiveExample liveExample = new LiveExample();
            List<Live> liveList = liveMapper.selectByExample(liveExample);
            PageHelper.clearPage();
            return liveList.stream()
                    .map(LiveResponse::new)
                    .map(item -> {
                        List<Product> products = liveDao.queryLiveProductByLiveId(item.getId());
                        if (null != products && products.size() > 0) {
                            Collections.shuffle(products);
                        }
                        item.setProductResponseList(products.stream()
                                .map(ProductResponse::new)
                                .collect(Collectors.toList()));
                        item.setDynamicType("LIVE");
                        return item;
                    }).collect(Collectors.toList());
        } else {
            List<Dynamic> dynamics = dynamicDao.queryDynamicList();
            Collections.shuffle(dynamics);
            return dynamics.stream()
                    .map(this::newDynamicResponse)
                    .collect(Collectors.toList());
        }

    }


    private DynamicResponse newDynamicResponse(Dynamic item) {
        DynamicResponse dynamicResponse = new DynamicResponse();
        BeanUtils.copyProperties(item, dynamicResponse);
        dynamicResponse.setIsActivity(StringUtil.isEmpty(item.getActivityType()) ? IsActivityConstant.NO : IsActivityConstant.YES);
        UsersDto usersDto = usersClient.getUsersInfo(dynamicResponse.getUserId());
        // 是否喜欢
        int praise = this.isPraise(item);
        Random random = new Random();
        int number = random.nextInt(10)+1;
        dynamicResponse.setVolumeStr(number+"W");
        dynamicResponse.setUserName(usersDto.getNickname());
        dynamicResponse.setHeadImg(usersDto.getHeadImg());
        dynamicResponse.setDynamicType("VIDEO");
        dynamicResponse.setIsLike(praise);
        return dynamicResponse;
    }

    // 是否点赞
    public int isPraise(Dynamic dynamic) {
        DynamicLikeExample dynamicLikeExample = new DynamicLikeExample();
        dynamicLikeExample.createCriteria()
                .andUserIdEqualTo(dynamic.getUserId())
                .andDynamicIdEqualTo(dynamic.getId());
        List<DynamicLike> dynamicLikeList = dynamicLikeMapper.selectByExample(dynamicLikeExample);
        if(dynamicLikeList != null && dynamicLikeList.size() > 0) {
            return DynamicConstant.IS_LKIE_YES;
        } else {
            return DynamicConstant.IS_LIKE_NO;
        }
    }

    @Override
    public DynamicDto getDynamicById(Integer id) {
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(id);
        DynamicDto dynamicDto = new DynamicDto();
        BeanUtils.copyProperties(dynamic, dynamicDto);
        return dynamicDto;
    }

    @Override
    public Integer getDynamicCountByUserId(Integer userId) {
        DynamicExample example = new DynamicExample();
        example.createCriteria().andUserIdEqualTo(userId).andStatusEqualTo((byte)DynamicStatusEnums.PASS.getCode());
        long count = dynamicMapper.countByExample(example);
        return Integer.parseInt(String.valueOf(count));
    }

    @Override
    public Integer getDynamicCountByUserId(Integer userId, Integer status) {
        DynamicExample example = new DynamicExample();
        DynamicExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        if (null != status) {
//            criteria.andStatusEqualTo(status.byteValue());
            List<Byte> statusList = new ArrayList<>();
            statusList.add(status.byteValue());
            if (status.equals(1)) {
                statusList.add((byte)0);
            }
            criteria.andStatusIn(statusList);
        }
        long count = dynamicMapper.countByExample(example);
        return Integer.parseInt(String.valueOf(count));
    }

    @Override
    public List<DynamicResponse> getOthersDynamicList(Integer userId,Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<Dynamic> dynamicList;
        // v1 v2 版本 只查询 活动商品 跟 普通商品的数据
        if(!"v3".equals(TokenUtil.getRequest().getHeader("api-ver"))){
            DynamicExample dynamicExample = new DynamicExample();
            dynamicExample.createCriteria()
                    .andUserIdEqualTo(userId)
                    .andProductTypeIn(Arrays.asList(1,2))
                    .andStatusIn(Arrays.asList(DynamicConstant.DYNAMIC_STATUS_PASS, DynamicConstant.DYNAMIC_STATUS_PASSING));
            dynamicList = dynamicMapper.selectByExample(dynamicExample);
        }else{
            dynamicList = dynamicDao.getDynamicListByUserId(userId);
        }
        return dynamicList.stream()
                .map(DynamicResponse::new)
                .collect(Collectors.toList());
    }

    @Override
    public DynamicCommentResponse addCommentV2(CommentRequest request, UsersResponse currentUser) {
        if (SensitiveWordUtil.contains(request.getContent())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SENSITIVE_WORDS));
        }
        JSONObject jsonObject = WxUtils.msgSecCheck(commonService.getSysConfigValue(SysConfigConstants.WX_TOKEN), request.getContent());
        if (WxCodeEnums.CODE_87014.getCode().equals(jsonObject.getInteger("errCode"))) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SENSITIVE_WORDS));
        }
//        int score = doGiveScore(request.getUserId());
        DynamicComment dynamicComment = new DynamicComment();
        dynamicComment.setContent(request.getContent());
        dynamicComment.setCreateTime(new Date());
        dynamicComment.setDynamicId(request.getDynamicId());
        dynamicComment.setUserId(request.getUserId());
        dynamicComment.setLikeNum(0);
        dynamicComment.setSort(1);
        dynamicComment.setPid(Optional.ofNullable(request.getPid())
                .orElse(0));
        dynamicComment.setStatus(0);
//        dynamicComment.setStarLevel(request.getStarLevel());
//        dynamicComment.setFlag(request.getFlag());
//        dynamicComment.setScore(score);
        int dynamicCommentId = dynamicCommentMapper.insertSelective(dynamicComment);
        // 动态评论数 + 1
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(request.getDynamicId());
        dynamic.setCommentNum(dynamic.getCommentNum() + 1);
        dynamicMapper.updateByPrimaryKeySelective(dynamic);

        // 商品浏览记录
        BrowsingHistoryRequest browsingHistoryRequest = new BrowsingHistoryRequest();
        browsingHistoryRequest.setDynamicId(request.getDynamicId());
        saveBrowsingHistory(browsingHistoryRequest,request.getUserId(),DynamicOperationEnum.COMMENT.name());

        DynamicCommentResponse dynamicCommentResponse = new DynamicCommentResponse();
        dynamicCommentResponse.setHeadImg(currentUser.getHeadImg());
        dynamicCommentResponse.setNickname(currentUser.getNickname());
        dynamicCommentResponse.setContent(request.getContent());
        dynamicCommentResponse.setId(dynamicCommentId);
        dynamicCommentResponse.setCreateTime(new Date());
        dynamicCommentResponse.setContent(request.getContent());
        dynamicCommentResponse.setDynamicId(request.getDynamicId());
        dynamicCommentResponse.setUserId(request.getUserId());
        dynamicCommentResponse.setLikeNum(0);
        dynamicCommentResponse.setPid(Optional.ofNullable(request.getPid())
                .orElse(0));
        dynamicCommentResponse.setDynamicCommentResponses(new ArrayList<>());

        DynamicCommentDto dynamicCommentDto = new DynamicCommentDto();
        try {
            log.info("===新增评论埋点===");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String uuid = TokenUtil.getRequest().getHeader("uuid");
            String ip = IPUtil.getIpAddress(TokenUtil.getRequest());
            String channel = TokenUtil.getChannel();
            String source = TokenUtil.getSource();//ios/android
            dynamicCommentDto.setDynamicId(request.getDynamicId().toString());
            dynamicCommentDto.setId(String.valueOf(dynamic.getId()));
            dynamicCommentDto.setChannel(channel);
            dynamicCommentDto.setPlatform(source);
            dynamicCommentDto.setIp(ip);
            dynamicCommentDto.setUserId(request.getUserId().toString());
            dynamicCommentDto.setCreateTime(sdf.format(new Date()));
            dynamicCommentDto.setType(1);
            dynamicCommentDto.setUuid(uuid);
//            rabbitTemplate.convertAndSend(QueueConstants.APP_DYNAMICCOMMENT, JSONObject.toJSONString(dynamicCommentDto));
        } catch (Exception e){
            log.error("===新增评论埋点异常==={}", JSONObject.toJSONString(dynamicCommentDto));
        }

//        dynamicCommentResponse.setScore(score);
        return dynamicCommentResponse;
    }

    /**
    * 根据专区Id获取专区下商品的测评列表
    * @param specialId:
    * @returns: java.util.List<com.ytjj.qmyx.mall.model.Dynamic>
    * 
    */
    @Override
    public List<DynamicVO> getDynamicBySpecialId(Integer specialId) {
        String type = "COMPOSITE";
        String strings =  redisService.get("productsFromFrontCategoryIds:"+type+":"+specialId);
        //1.当前分类下的商品Id集合
        List<Integer> ids = new ArrayList<>();
        if(strings == null){//redis该专区下商品id为空
            //通过专区id找专区信息
            FrontCategory frontCategory = frontCategoryMapper.selectByPrimaryKey(specialId);
            //获取分类id
            String categoryListStr = frontCategory.getCategoryList();
            if (StringUtils.isEmpty(categoryListStr)) {
                return null;
            }
            String[] split = categoryListStr.split(",");
            for (String s : split) {
                ids.add(Integer.valueOf(s));
            }
            //通过专区里的分类id获取到分类对象集合
            List<ProductCategoryResp> list = productDao.selectCategoryByIds(ids);
            //分类集合进行排序(三级放二级,二级放一级里)
            List<ProductCategoryResp> productCategoryResp = productServiceImpl.getProductCategoryResps(list);

            List<Integer> categoryIds = productServiceImpl.getCategoryIds(productCategoryResp);
            if(CollectionUtils.isEmpty(categoryIds)){
                return new ArrayList<>();
            }
            List<Product> productList = productDao.selectProductByCategoryIds(categoryIds, null, TokenUtil.getDataType(), TokenUtil.getPlatformData());
            ids = productList.stream().map(Product::getId).collect(Collectors.toList());
        } else {
            String[] split = strings.split(",");
            for (String s1 : split) {
                if (StringUtils.isNotEmpty(s1)) {
                    ids.add(Integer.valueOf(s1));
                }
            }
        }
        if(CollectionUtils.isEmpty(ids)){
            return new ArrayList<>();
        }
        //2.当前商品下的所有测评
        List<DynamicVO> dynamics =  dynamicDao.selectByProductIds(ids);
        return dynamics;
    }

    @Override
    public CommonResult getFiveSuperiorDynamic() {
        List<FiveSpuriorDynamicResponse> responses = dynamicDao.getFiveSuperiorDynamic();
        if (CollectionUtils.isEmpty(responses)){
            return CommonResult.success();
        }
        responses.stream().forEach(response ->{
            if (null != response.getProductPrice()){
                response.setEarnMoney(response.getProductPrice().multiply(new BigDecimal(0.34)).setScale(1, RoundingMode.HALF_UP));
            }else {
                response.setEarnMoney(BigDecimal.valueOf(10));
            }
            if (null == response.getPraiseNum()){
                response.setPraiseNum(0);
            }
            if (response.getPraiseNum() <= 2000){
                response.setExposure("10000+");
            }else if (2000 <= response.getPraiseNum() && response.getPraiseNum()<= 5000){
                response.setExposure("15000+");
            }else if (5000 <= response.getPraiseNum() && response.getPraiseNum()<= 10000){
                response.setExposure("20000+");
            }else if (10000 <= response.getPraiseNum()){
                response.setExposure("30000+");
            }
        });
        return CommonResult.success(responses);
    }

    @Override
    public Map<String,Object> getDynamicComments(DynamicCommentRequest dynamicCommentRequest) {
        PageHelper.startPage(dynamicCommentRequest.getPageNum(),dynamicCommentRequest.getPageSize());
        //获得动态的评论列表
        List<DynamicCommentResponse> commentsByDynamicId = dynamicCommentDao.getCommentsByDynamicId(dynamicCommentRequest);
        //获得评论和回复的总数
        long total =  dynamicCommentDao.getTotalCommentsByDynamicId(dynamicCommentRequest.getDynamicId());
        //构造查询回复的请求参数
        DynamicCommentReplyRequest dynamicCommentReplyRequest = new DynamicCommentReplyRequest();
        dynamicCommentReplyRequest.setPageNum(1);
        //默认取一条回复
        dynamicCommentReplyRequest.setPageSize(1);
        dynamicCommentReplyRequest.setDynamicId(dynamicCommentRequest.getDynamicId());
        dynamicCommentReplyRequest.setDynamicAuthorId(dynamicCommentRequest.getDynamicAuthorId());
        dynamicCommentReplyRequest.setUserId(dynamicCommentRequest.getUserId());
        //1.封装返回实体
        commentsByDynamicId.stream().forEach(e->{
            //1.1获得该评论下的回复
            dynamicCommentReplyRequest.setCommentId(e.getId());
            CommonPage<DynamicCommentReplyResponse> dynamicCommentReplys = getDynamicCommentReplys(dynamicCommentReplyRequest);
            e.setReplyTotal(dynamicCommentReplys.getTotal());
            e.setDynamicCommentReplyResponses(dynamicCommentReplys.getList());

            //1.2是否是测评的作者
            if (e.getUserId().equals(dynamicCommentRequest.getDynamicAuthorId())) {
                e.setIsAuthor(1);
            } else {
                e.setIsAuthor(0);
            }

            //1.3是否是否是当前用户的评论
            if(e.getUserId().equals(dynamicCommentRequest.getUserId())){
                e.setIsMine(1);
            }else{
                e.setIsMine(0);
            }
            //1.4设置是否点赞评论
            e.setIsLikeComment(this.isClickLike(e.getId(),0,dynamicCommentRequest.getDynamicId(),dynamicCommentRequest.getUserId()) ? 1 : 0);
        });
        Map<String,Object> map = new HashMap<>();
        PageInfo<DynamicCommentResponse> pageInfo = new PageInfo<>(commentsByDynamicId);
        map.put("pageNum",pageInfo.getPageNum());
        map.put("pageSize",pageInfo.getPageSize());
        map.put("total",total);
        map.put("list",pageInfo.getList());
        return map;
    }

    @Override
    public CommonPage<DynamicCommentReplyResponse> getDynamicCommentReplys(DynamicCommentReplyRequest dynamicCommentReplyRequest) {
        PageHelper.startPage(dynamicCommentReplyRequest.getPageNum(),dynamicCommentReplyRequest.getPageSize());
        List<DynamicCommentReplyResponse> replyByCommentId = dynamicCommentReplyDao.getReplyByCommentId(dynamicCommentReplyRequest);
        //1.封装返回实体
        replyByCommentId.stream().forEach(e->{
            //1.1是否是测评的作者
            if (e.getUserId().equals(dynamicCommentReplyRequest.getDynamicAuthorId())) {
                e.setIsAuthor(1);
            } else {
                e.setIsAuthor(0);
            }

            //1.2是否是否是当前用户的评论
            if(e.getUserId().equals(dynamicCommentReplyRequest.getUserId())){
                e.setIsMine(1);
            }else{
                e.setIsMine(0);
            }
            //1.3设置是否点赞
            e.setIsLikeComment(this.isClickLike(e.getId(),1,dynamicCommentReplyRequest.getDynamicId(),dynamicCommentReplyRequest.getUserId()) ? 1 : 0);
        });
        return CommonPage.restPage(replyByCommentId);
    }

    @Override
    public DynamicCommentResponse addCommentForDynamic(DynamicCommentRequest dynamicCommentRequest) {
        if(StringUtils.isEmpty(dynamicCommentRequest.getContent())){
            throw new ApiException("内容不能为空");
        }
        DynamicComment dynamicComment = new DynamicComment();
        BeanUtils.copyProperties(dynamicCommentRequest,dynamicComment);
        dynamicComment.setSort(0);
        dynamicComment.setPid(0);
        dynamicComment.setCreateTime(new Date());
        dynamicComment.setLikeNum(0);
        dynamicComment.setIsShow(0);
        dynamicComment.setIsDeleted(0);
        dynamicComment.setStatus(0);
        dynamicComment.setScore(0);
        int i = dynamicCommentMapper.insertSelective(dynamicComment);
        if (i>0){
            DynamicCommentResponse comment = dynamicCommentDao.getCommentId(dynamicComment.getId());
            //1.1是否是测评的作者
            if (comment.getUserId().equals(dynamicCommentRequest.getDynamicAuthorId())) {
                comment.setIsAuthor(1);
            } else {
                comment.setIsAuthor(0);
            }
            //1.2是否是否是当前用户的评论
            comment.setIsMine(1);
            //1.3设置是否点赞
            comment.setIsLikeComment(0);
            return comment;
        }else{
            throw new ApiException("评论失败");
        }
    }

    @Override
    public DynamicCommentReplyResponse addCommentReply(DynamicCommentReplyRequest dynamicCommentReplyRequest) {
        if(StringUtils.isEmpty(dynamicCommentReplyRequest.getContent())){
            throw new ApiException("内容不能为空");
        }
        DynamicCommentReply dynamicCommentReply = new DynamicCommentReply();
        BeanUtils.copyProperties(dynamicCommentReplyRequest,dynamicCommentReply);
        dynamicCommentReply.setLikeNum(0);
        dynamicCommentReply.setSort(0);
        dynamicCommentReply.setCreateTime(new Date());
        dynamicCommentReply.setIsDeleted(0);
        dynamicCommentReply.setIsShow(0);
        int i = dynamicCommentReplyMapper.insertSelective(dynamicCommentReply);
        if (i > 0) {
            DynamicCommentReplyResponse replyEntity = dynamicCommentReplyDao.getReplyById(dynamicCommentReply.getId());
            //1.1是否是测评的作者
            if (replyEntity.getUserId().equals(dynamicCommentReplyRequest.getDynamicAuthorId())) {
                replyEntity.setIsAuthor(1);
            } else {
                replyEntity.setIsAuthor(0);
            }
            //1.2是否是否是当前用户的评论
            replyEntity.setIsMine(1);
            //1.3设置是否点赞
            replyEntity.setIsLikeComment(0);
            return replyEntity;
        }else{
            throw new ApiException("回复失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean clickLike(Integer type,Integer id,Integer userId,Integer dynamicId) {
        //判断是否点赞
        if(isClickLike(id,type,dynamicId,userId)){
            //1.已点赞则取消点赞
            //1.1当前评论点赞数减1
            dynamicCommentDao.commentLikeIncr(type,id,-1);
            //1.2删除当前用户的点赞记录
            DynamicCommentLikeExample dynamicCommentLikeExample = new DynamicCommentLikeExample();
            if(type == 0){//当前为评论
                dynamicCommentLikeExample.createCriteria().andUserIdEqualTo(userId).andCommentIdEqualTo(id).andDynamicIdEqualTo(dynamicId);
                dynamicCommentLikeMapper.deleteByExample(dynamicCommentLikeExample);
            }else if(type == 1){//当前为回复
                dynamicCommentLikeExample.createCriteria().andUserIdEqualTo(userId).andReplyIdEqualTo(id).andDynamicIdEqualTo(dynamicId);
                dynamicCommentLikeMapper.deleteByExample(dynamicCommentLikeExample);
            }
        }else{
            //1.未点赞则记录点赞
            //1.1当前评论点赞数加1
            dynamicCommentDao.commentLikeIncr(type,id,1);
            DynamicCommentLike dynamicCommentLike = new DynamicCommentLike();
            dynamicCommentLike.setUserId(userId);
            dynamicCommentLike.setDynamicId(dynamicId);
            dynamicCommentLike.setCreateTime(new Date());
            //1.2记录用户的点赞
            if(type == 0){//当前为评论
                dynamicCommentLike.setCommentId(id);
                dynamicCommentLike.setReplyId(0);
                dynamicCommentLikeMapper.insertSelective(dynamicCommentLike);
            }else if (type == 1){//当前为回复
                dynamicCommentLike.setReplyId(id);
                dynamicCommentLike.setCommentId(0);
                dynamicCommentLikeMapper.insertSelective(dynamicCommentLike);
            }
        }
        return true;
    }

    @Override
    public boolean isClickLike(Integer id, Integer type,Integer dynamicId,Integer userId) {
        long count = 0;
        if(userId == null || userId == 0)
            return false;
        if(type == 0){//评论
            DynamicCommentLikeExample dynamicCommentLikeExample = new DynamicCommentLikeExample();
            dynamicCommentLikeExample.createCriteria().andDynamicIdEqualTo(dynamicId).andCommentIdEqualTo(id).andUserIdEqualTo(userId);
            count = dynamicCommentLikeMapper.countByExample(dynamicCommentLikeExample);
        }else if(type == 1){//回复
            DynamicCommentLikeExample dynamicCommentLikeExample = new DynamicCommentLikeExample();
            dynamicCommentLikeExample.createCriteria().andDynamicIdEqualTo(dynamicId).andReplyIdEqualTo(id).andUserIdEqualTo(userId);
            count = dynamicCommentLikeMapper.countByExample(dynamicCommentLikeExample);
        }
        return count > 0 ? true : false;
    }

    @Override
    public List<DynamicVO> relatedDynamicRecommend(Integer id) {
        List<String> platform = new ArrayList<>();
        platform.add("all");
        platform.add(TokenUtil.getPlatformData());
        Dynamic dynamic = dynamicMapper.selectByPrimaryKey(id);
        Product product = productMapper.selectByPrimaryKey(Optional.ofNullable(dynamic).map(e->e.getProductId()).orElseGet(()->{throw new ApiException("当前测评不存在");}));
        return getDynamicsByBottomCategoryId(product,platform,id);
    }

    /**
     * 根据三级分类获取测评列表
     * v4.2.2
     * @param product:商品
     * @returns: java.util.List<com.ytjj.qmyx.mall.model.vo.DynamicVO>
     * 
     */
    public List<DynamicVO> getDynamicsByBottomCategoryId(Product product,List<String> platform,Integer dynamicId){
        if(product.getBottomCategoryId() == null){
            log.error("当前商品的三级分类不存在");
            //随机推荐6条
            return dynamicDao.selectByRand(6,dynamicId);
        }
        Integer bottomCategoryId = product.getBottomCategoryId();
        List<DynamicVO> dynamicVOS = new ArrayList<>();
        ProductExample productExample = new ProductExample();
        productExample.createCriteria().andBottomCategoryIdEqualTo(bottomCategoryId).andStatusEqualTo((byte)1)
                .andDataTypeEqualTo(TokenUtil.getDataType()).andIsAdvertEqualTo(0).andIsHideEqualTo(0).andPlatformDataIn(platform).andIdNotEqualTo(product.getId());
        //1.获得当前三级分类下的商品
        List<Product> products = productMapper.selectByExample(productExample);
        if(products.size() == 0){
            //2.1商品不存在,即不存在测评，则取当前三级分类兄弟类的测评
            dynamicVOS = this.getProductByBottomCategoryId(bottomCategoryId,platform,dynamicVOS,dynamicId,product.getId());
        }else{
            //2.商品Id集合
            List<Integer> collect = products.stream().map(e -> e.getId()).collect(Collectors.toList());
            //2.1分类下存在商品，则查询商品的测评集合
            List<DynamicVO> dynamicVOS1 = dynamicDao.selectByProductIds(collect);
            if(dynamicVOS1.size() >= 6){
                //只取前6条
                dynamicVOS = dynamicVOS1.subList(0,6);
            }else{
                //相关测评数不足6条，则取当前三级分类兄弟类的测评
                dynamicVOS = this.getProductByBottomCategoryId(bottomCategoryId,platform,dynamicVOS1,dynamicId,product.getId());
            }
        }
        return dynamicVOS;
    }

    /**
    * 获取当前三级分类的兄弟分类的测评集合 兄弟分类如：[1,2,3:[4,5,6]] 如果当前三级分类是6，则兄弟分类是[4，5,6]
    * v4.2.2
    * @param bottomCategoryId:
    * @returns: java.util.List<com.ytjj.qmyx.mall.model.Product>
    * 
    */
    public List<DynamicVO> getProductByBottomCategoryId(Integer bottomCategoryId,List<String> platform,List<DynamicVO> dynamicVOS,Integer dynamicId,Integer productId){
        //三级分类
        ProductCategory productCategory = productCategoryMapper.selectByPrimaryKey(bottomCategoryId);
        if(productCategory == null)
            throw new ApiException("当前测评的商品的三级分类不存在");
        ProductCategoryExample productCategoryExample = new ProductCategoryExample();
        productCategoryExample.createCriteria().andPidEqualTo(productCategory.getPid()).andStatusEqualTo((byte)1).andIdNotEqualTo(bottomCategoryId);
        //兄弟分类集合
        List<ProductCategory> productCategories = productCategoryMapper.selectByExample(productCategoryExample);
        if(CollectionUtils.isEmpty(productCategories)){
            throw new ApiException("异常：当前三级分类不存在");
        }
        for (ProductCategory item : productCategories) {
            ProductExample productExample = new ProductExample();
            productExample.createCriteria().andBottomCategoryIdEqualTo(item.getId()).andStatusEqualTo((byte)1)
                    .andDataTypeEqualTo(TokenUtil.getDataType()).andIsAdvertEqualTo(0).andIsHideEqualTo(0).andPlatformDataIn(platform).andIdNotEqualTo(productId);
            List<Product> products = productMapper.selectByExample(productExample);
            List<Integer> ids = products.stream().map(e->e.getId()).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(ids)){
                continue;
            }
            List<DynamicVO> dynamicVOS2 = dynamicDao.selectByProductIds(ids);
            dynamicVOS.addAll(dynamicVOS2);
            if(dynamicVOS.size() >= 6){
                return dynamicVOS.subList(0,6);
            }
        }
        //如果还不足6条，则随机补充除当前测评外的6-n条测评
        dynamicVOS.addAll(dynamicDao.selectByRand(6-dynamicVOS.size(),dynamicId));
        return dynamicVOS;
    }
}
